import json
import cv2
import numpy as np
from PIL import Image,ImageDraw,ImageFont
def get_strarray(com_str):
    str_list = []
    for i in com_str:
        background = np.ones((90,90,3),np.uint8)*255
        img = Image.fromarray(background)
        draw = ImageDraw.Draw(img)
        font = ImageFont.truetype('C:\Windows\Fonts\msyhbd.ttc',85)
        draw.text((10,-15),i,fill='black',font=font)
        # font = cv2.FONT_HERSHEY_PLAIN  # 定义字体
        # cv2.putText(background, '000', (10, -20), font, 90, (0, 0, 0), 2)
        # 异常值捕获
        # if com_str.index(i)==0:
        # img.show()
        #     img.save('deal_com.png')
        img = np.array(img)
        str_list.append(img)
    return str_list

def get_imgarray(img_path):
    xx = img_path
    img_list = []
    for i in range(3):
        for j in range(3):
            img = np.array(xx[(10*(i+1)+90*i):(10*(i+1)+90*(i+1)),(10*(j+1)+90*j):(10*(j+1)+90*(j+1))])
            img = np.array(img)
            #  异常值捕获
            # if (i==0)&(j==0):
            #     image = Image.fromarray(img)
            #     image.save('deal_com_0.png')
            #     image.show() 
            img_list.append(img)
            pass
        pass
    return img_list

def get_index(com_str,img_path):
    str_array = get_strarray(com_str)
    img_array = get_imgarray(img_path)
    str_dict = {}
    ixi = []
    for str_index in range(len(str_array)):
        img_list = []
        for img_index in range(len(img_array)):
            str = str_array[str_index]
            cxa = str==img_array[img_index]
            cxa = np.uint8(cxa)
            cxa[np.all(cxa!=[1,1,1],axis=-1)] = (255,255,255)
            cxa[np.all(cxa==[1,1,1],axis=-1)] = (0,0,0)
            # 异常值捕获
            # if str_index == 0:
            #     if img_index in [0,3]:
            #         ixi.append(cxa[np.all(cxa==[255,255,255],axis=-1)].shape[0])
            #         image = Image.fromarray(cxa)
            #         image.show()
            #         pass
            #     pass
            bxa = cxa[np.all(cxa==[0,0,0],axis=-1)]
            img_list.append(len(bxa))
            index_ = img_list.index(max(img_list))
            if img_index==index_:
                dxa = cxa
        str_dict[index_] = dxa
        pass
    # for i in list(str_dict.keys()):
    #     # 图差
    #     data = str_dict[i]
    #     # image = Image.fromarray(data)
    #     # image.show()
    #     # image.close()
    #     cv2.imshow('tu cha', data)
    #     cv2.waitKey(0)
    #     # cv2.destroyAllWindows()
    #     # 可以轻易删除任何我们建立的窗口，括号内输入想删除的窗口名
    #     cv2.destroyAllWindows()
    return get_position(list(str_dict.keys()),com_str)

def get_position(img_index,com_str):
    positions = [157,167,177,427,437,447,727,737,747]
    if len(img_index)<len(com_str):
        print('发生同位替换')
        # 对于字体转图后的预处理,主要针对字体的厚度,或者更改字体大小'
    position = [str(positions[i]) for i in img_index]
    return position


def erode_image(img_path):
    # cv2.imread读取图像
    im = img_path
    # img.shape可以获img_path得图像的形状，返回值是一个包含行数，列数，通道数的元组 (100, 100, 3)
    h, w = im.shape[0:2]
    # 去掉黑椒点的图像
    # np.all()函数用于判断整个数组中的元素的值是否全部满足条件，如果满足条件返回True，否则返回False
    im[np.all(im == [0, 0, 0], axis=-1)] = (255, 255, 255)
    # reshape：展平成n行3列的二维数组
    # np.unique()该函数是去除数组中的重复数字，并进行排序之后输出
    colors, counts = np.unique(np.array(im).reshape(-1, 3), axis=0, return_counts=True)
    # 筛选出现次数在500~2200次的像素点
    # 通过后面的操作就可以移除背景中的噪点
    info_dict = {counts[i]: colors[i].tolist() for i, v in enumerate(counts) if int(v) < 2200}

    # 移除了背景的图片
    remove_background_rgbs = info_dict.values()
    mask = np.zeros((h, w, 3), np.uint8) + 255# 生成一个全是白色的图片
    # 通过循环将不是噪点的像素,赋值给一个白色的图片,最后到达移除背景图片的效果
    for rgb in remove_background_rgbs:
        mask[np.all(im == rgb, axis=-1)] = im[np.all(im == rgb, axis=-1)]
    # cv2.imshow("Image with background removed", mask)  # 移除了背景的图片

    # 去掉线条,全部像素黑白化
    line_list = []# 首先创建一个空列表,用来存放出现在间隔当中的像素点
    # 两个for循环,遍历9000次
    for y in range(h):
        for x in range(w):
            tmp = mask[x, y].tolist()
            if tmp != [0, 0, 0]:
                if 110 < y < 120 or 210 < y < 220:
                    line_list.append(tmp)
                if 100 < x < 110 or 200 < x < 210:
                    line_list.append(tmp)
    remove_line_rgbs = np.unique(np.array(line_list).reshape(-1, 3), axis=0)
    for rgb in remove_line_rgbs:
        mask[np.all(mask == rgb, axis=-1)] = [255, 255, 255]
    # np.any()函数用于判断整个数组中的元素至少有一个满足条件就返回True，否则返回False。
    mask[np.any(mask != [255, 255, 255], axis=-1)] = [0, 0, 0]
    # cv2.imshow("Image with lines removed", mask)  # 移除了线条的图片

    # 腐蚀
    # 卷积核涉及到python形态学处理的知识,感兴趣的可以自行百度
    # 生成一个2行三列数值全为1的二维数字,作为腐蚀操作中的卷积核
    kernel = np.ones((2, 3), 'uint8')
    erode_img = cv2.erode(mask, kernel, cv2.BORDER_REFLECT, iterations=2)
    # cv2.imshow('Eroded Image', erode_img)
    # cv2.waitKey(0)
    # cv2.destroyAllWindows()可以轻易删除任何我们建立的窗口，括号内输入想删除的窗口名
    # cv2.destroyAllWindows()
    # cv2.imwrite('deal.png', erode_img)
    return erode_img



        




if __name__ == '__main__':
    import requests
    import json
    import base64
    import skimage.io
    # from lxml import etree
    import re
    session = requests.Session()
    headers = {
        'cookies':'sessionid=123456'
    }
    res = session.get('https://match.yuanrenxue.com/api/match/8_verify')
    cookie = dict(res.cookies).get('sessionid')
    res = json.loads(res.text)['html']
    # html = etree.HTML(res['html'])
    com_str = re.findall('<p>(\w)</p>',res)
    img_code = re.search('data:image/jpeg;base64,(.*)\"\s',res)[1]
    img_b64 = base64.b64decode(img_code)
    img = skimage.io.imread(img_b64, plugin='imageio')
    img = erode_image(img)
    index_ = get_index(com_str,img)
    if len(index_)!=4:
        exit
    params = {
        'page':1,
        'answer':f'{"|".join(index_)+"|"}'
    }
    res = session.get(
        url = 'https://match.yuanrenxue.com/api/match/8',
        params=params
    )
    print(res.json())
    pass
